
#ifndef MUSICPLAYER_H
#define MUSICPLAYER_H

#include <QWidget>
#include <QMediaPlayer>

class VolumeButton;

// 通过前向声明这些类，可以在不包含其定义的情况下使用指针或引用来声明变量或函数参数。这样可以提高编译速度和减少依赖关系。
QT_FORWARD_DECLARE_CLASS(QLabel)
QT_FORWARD_DECLARE_CLASS(QSlider)
QT_FORWARD_DECLARE_CLASS(QAbstractButton)
QT_FORWARD_DECLARE_CLASS(QWinTaskbarButton)
QT_FORWARD_DECLARE_CLASS(QWinTaskbarProgress)
QT_FORWARD_DECLARE_CLASS(QWinThumbnailToolBar)
QT_FORWARD_DECLARE_CLASS(QWinThumbnailToolButton)

/*
    QLabel：用于显示文本或图像的标签控件。
    QSlider：用于选择一个范围内的值的滑块控件。
    QAbstractButton：抽象类，用于表示按钮控件的基类。
    QWinTaskbarButton：Windows特定的类，用于管理任务栏按钮。
    QWinTaskbarProgress：Windows特定的类，用于在任务栏上显示进度条。
    QWinThumbnailToolBar：Windows特定的类，用于在任务栏上显示缩略图工具栏。
    QWinThumbnailToolButton：Windows特定的类，用于在任务栏上显示缩略图工具栏按钮。
*/

class MusicPlayer : public QWidget
{
    Q_OBJECT
public:
    explicit MusicPlayer(QWidget *parent = nullptr);

    // 类内静态函数
    static QStringList supportedMimeTypes();
    static QStringList supportedSuffixes();

// 公有槽
public slots:
    void openFile();
    void playUrl(const QUrl& url);
    void togglePlayback();
    void seekForward();
    void seekBackward();

    // 事件：基类虚函数
protected:
/*
bool event(QEvent *event) override: 该函数用于处理所有的事件，包括鼠标事件、键盘事件、绘图事件等。在重写该函数时，需要根据不同的事件类型进行相应的处理，并返回一个布尔值表示是否已处理该事件。
void showEvent(QShowEvent *event) override: 当窗口部件被显示时，该函数会被调用。在重写该函数时，可以执行一些在窗口显示时需要进行的操作。
void dragEnterEvent(QDragEnterEvent *event) override: 当有拖放操作进入窗口部件时，该函数会被调用。在重写该函数时，可以根据拖放的数据类型和内容进行相应的处理。
void dropEvent(QDropEvent *event) override: 当有拖放操作在窗口部件上释放时，该函数会被调用。在重写该函数时，可以根据拖放的数据类型和内容进行相应的处理。
void mousePressEvent(QMouseEvent *event) override: 当鼠标按下时，该函数会被调用。在重写该函数时，可以获取鼠标的位置和按键信息，并执行相应的操作。
void mouseMoveEvent(QMouseEvent *event) override: 当鼠标移动时，该函数会被调用。在重写该函数时，可以获取鼠标的位置信息，并执行相应的操作。
void mouseReleaseEvent(QMouseEvent *event) override: 当鼠标释放时，该函数会被调用。在重写该函数时，可以获取鼠标的位置和按键信息，并执行相应的操作。
*/
    bool event(QEvent *event) override;
    void showEvent(QShowEvent *event) override;
    void dragEnterEvent(QDragEnterEvent *event) override;
    void dropEvent(QDropEvent *event) override;
    void mousePressEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;
    void mouseReleaseEvent(QMouseEvent *event) override;

    // 私有槽：一般用于当前类对象之间互相通信
private slots:
    void stylize();
    void updateState(QMediaPlayer::State state);
    void updatePosition(qint64 position);
    void updateDuration(qint64 duration);
    void setPosition(int position);
    void updateInfo();
    void handleError();

    void updateTaskbar();
    void updateThumbnailToolBar();

private:
    // 私有函数：不希望其他类访问
    void createWidgets();
    void createShortcuts();
    void createJumpList();
    void createTaskbar();
    void createThumbnailToolBar();

    // 正确的初始化指针 防止悬空指针 非法访问指针 空指针等
    QWinTaskbarButton *taskbarButton = nullptr;
    QWinTaskbarProgress *taskbarProgress = nullptr;
    QWinThumbnailToolBar *thumbnailToolBar = nullptr;
    QWinThumbnailToolButton *playToolButton = nullptr;
    QWinThumbnailToolButton *forwardToolButton = nullptr;
    QWinThumbnailToolButton *backwardToolButton = nullptr;

    QMediaPlayer mediaPlayer;   // 允许播放一个媒体源代码 栈对象

    QAbstractButton *playButton = nullptr;
    VolumeButton *volumeButton = nullptr;
    QSlider *positionSlider = nullptr;
    QLabel *positionLabel = nullptr;
    QLabel *infoLabel = nullptr;
    QPoint offset;
    QString fileName;
};

#endif // MUSICPLAYER_H
